package com.jh.user.util;

import net.lingala.zip4j.core.ZipFile;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class FileToZip {

    private static Logger log = LoggerFactory.getLogger(FileToZip.class);

    private FileToZip() {
    }

    /**
     * 将存放在sourceFilePath目录下的源文件，打包成fileName名称的zip文件，并存放到zipFilePath路径下
     *
     * @param sourceFilePath :待压缩的文件路径
     * @param zipFilePath    :压缩后存放路径
     * @param fileName       :压缩后文件的名称
     * @return
     */
    public static boolean fileToZip(String sourceFilePath, String zipFilePath, String fileName, HttpServletResponse response) {
        boolean flag = false;
        File sourceFile = new File(sourceFilePath);
        FileInputStream fis = null;
        BufferedInputStream bis = null;
        FileOutputStream fos = null;
        ZipOutputStream zos = null;
        OutputStream out = null;

        if (sourceFile.exists() == false) {
            log.info("待压缩的文件目录：" + sourceFilePath + "不存在.");
        } else {
            try {
                File zipFile = new File(zipFilePath + "/" + fileName + ".zip");
                ZipFile zFile = new ZipFile(zipFile);
                if (!zFile.isValidZipFile()) {
                    log.info(zipFilePath + "压缩文件不合法,可能被损坏.:" + fileName + ".zip" + "打包文件.");
                }
                File[] sourceFiles = sourceFile.listFiles();
                if (null == sourceFiles || sourceFiles.length < 1) {
                    log.info("待压缩的文件目录：" + sourceFilePath + "里面不存在文件，无需压缩.");
                } else {
                    fos = new FileOutputStream(zipFile);
                    zos = new ZipOutputStream(new BufferedOutputStream(fos));
                    byte[] bufs = new byte[1024 * 10];
                    for (int i = 0; i < sourceFiles.length; i++) {
                        //创建ZIP实体，并添加进压缩包
                        ZipEntry zipEntry = new ZipEntry(sourceFiles[i].getName());
                        zos.putNextEntry(zipEntry);
                        //读取待压缩的文件并写进压缩包里
                        fis = new FileInputStream(sourceFiles[i]);
                        bis = new BufferedInputStream(fis, 1024 * 10);
                        int read = 0;
                        while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                            zos.write(bufs, 0, read);
                        }
                    }
                    flag = true;
                }

                // 输出到客户端
                out = response.getOutputStream();
                response.reset();
                response.setHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes("GB2312"), "UTF-8"));
                response.setContentType("application/octet-stream; charset=utf-8");
                response.setCharacterEncoding("UTF-8");
                out.write(FileUtils.readFileToByteArray(zipFile));
                out.flush();
                out.close();
                if(flag){
                    for(int i = 0; i < sourceFiles.length; i++){
                        sourceFiles[i].delete();
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException(e);
            }finally {
                //关闭流
                try {
                    if (null != out) out.close();
                    if (null != bis) bis.close();
                    if (null != zos)
                        zos.finish();
                        zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            }
        }
        return flag;
    }

}
